/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control;

import entidad.Candidato;
import entidad.Cargo;
import entidad.Departamento;
import entidad.Empleado;
import entidad.Horario;
import entidad.HorarioDia;
import frontera.dao.DAO;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author tuareg
 */
public class AdministrarCargos extends Administrar<Cargo> {

	public String crearCargo(String nombre, Horario horario, String salarioBasico, Departamento departamento, 
                                 String nivelPermisos, String nuevoEstado,Calendar fechaDeModificacion) {

		String informacionValidacion = validarInformacion(nombre, salarioBasico, horario);
		
		if (informacionValidacion.equals("")) {
			
                        Cargo nuevoCargo = new Cargo( nombre, horario, salarioBasico, departamento, nuevoEstado, nivelPermisos,fechaDeModificacion);
			if(!SIRHApp.getInstance().getDAOHorario().crear(horario)){
                            return SIRHApp.errorBaseDatos("horario");
                        }
                        
                        for(HorarioDia hd : horario.getHorario()){
                            hd.setHorario(horario);
                            if(!SIRHApp.getInstance().getDAOHorarioDia().crear(hd)){
                                return SIRHApp.errorBaseDatos("horario dia");
                            }
                            
                        }
                        
                        if (!SIRHApp.getInstance().getSistema().agregarCargo(nuevoCargo)) {
				return SIRHApp.errorBaseDatos("cargo");
			}

			return "";
		}

		return informacionValidacion;
	}

	public String actualizarCargo(Cargo cargo, String nombre,
		String salarioBasico, Departamento departamento,
		String estado, String permisos, Horario horario) {

		String informacionValidacion = validarInformacion(nombre, salarioBasico, horario);
		Cargo actCargo = cargo;
		
                if (informacionValidacion.equals("")) {
			Cargo nuevoCargo = new Cargo(nombre, horario, salarioBasico, departamento, estado, permisos,Calendar.getInstance());
			String viejoEstado = actCargo.getEstado();
			
			String nuevoEstado = estado;
			Long viejoId = actCargo.getIdCargo();
			String tmp =  validarEstado(viejoEstado, nuevoEstado, viejoId);
                        
			if (!tmp.equals(""))
				return tmp;
                        
                        getDAO().actualizar(actCargo, nuevoCargo);

			return "";
		}

		return informacionValidacion;
	}
        
	public boolean eliminarCargo(Cargo borCargo) {
		return SIRHApp.getInstance().getSistema().eliminarCargo(borCargo);
	}

	private String validarEstado(String viejoEstado, String nuevoEstado, Long id) {
		
            if (viejoEstado.equals("Ocupado") && nuevoEstado.equals("Bloqueado") ) {
			ArrayList<Empleado> empleadosAsociados = SIRHApp.getInstance().getDAOEmpleado().getEmpleadosCargo(id);
			
                        for (Empleado e : empleadosAsociados) {
				if (!e.getEstado().equals("Despedido") && !e.getEstado().equals("Jubilado") ) {
					return "Este cargo tiene empleados activos asociados, para cambiar el estado a Bloqueado por favor cambie el cargo de estos empleados o cambie el estado de los empleados asociados a Despedido o Jubilado";
				}
			}
		}
            
		if (viejoEstado.equals("En Proceso") && nuevoEstado.equals("Ocupado") ) {
			ArrayList<Empleado> empleadosAsociados = SIRHApp.getInstance().getDAOEmpleado().getEmpleadosCargo(id);
			
                        if (empleadosAsociados.isEmpty()) {
				return "Este cargo no tiene ningún empleado asociado, para poder pasarlo al estado Ocupado por favor asignele algún empleado";

			} else {
				boolean activo = false;
				for (Empleado e : empleadosAsociados) {
					if (e.getEstado().equals("Activo")) {
						activo = true;
						break;
					}
				}
				if (!activo) {
					return "Este cargo no tiene ningún empleado activo asociado y por lo tanto no puede pasar al estado Ocupado";

				}
			}
			
                        ArrayList<Candidato> candidatosAsociados = SIRHApp.getInstance().getDAOCandidato().getCargoAsociado(id);
			
                        for (Candidato c : candidatosAsociados) {
				if (!c.getEstado().equals("Descartado")) {
					return "Este cargo tiene algún candidato no descartado asociado y por lo tanto no puede pasar al estado Bloqueado";

				}
			}
		}
		if (viejoEstado.equals("En Proceso") && nuevoEstado.equals("Bloqueado")) {
			ArrayList<Candidato> candidatosAsociados = SIRHApp.getInstance().getDAOCandidato().getCargoAsociado(id);
			
                        for (Candidato c : candidatosAsociados) {
				if (!c.getEstado().equals("Descartado")) {
					return "Este cargo tiene algún candidato no descartado asociado y por lo tanto no puede pasar al estado Bloqueado";

				}
			}
                        
			ArrayList<Empleado> empleadosAsociados = SIRHApp.getInstance().getDAOEmpleado().getEmpleadosCargo(id);
			
                        for (Empleado e : empleadosAsociados) {
				if (!e.getEstado().equals("Despedido") && !e.getEstado().equals("Jubilado")) {
					
					return "Este cargo tiene empleados activos asociados, para cambiar el estado a Bloqueado por favor cambie el cargo de estos empleados o cambie el estado de los empleados asociados a Despedido o Jubilado";

				}
			}

		}
		if (viejoEstado.equals("En Proceso") && nuevoEstado.equals("Vacante")) {
			ArrayList<Empleado> empleadosAsociados = SIRHApp.getInstance().getDAOEmpleado().getEmpleadosCargo(id);
			
                        if (!empleadosAsociados.isEmpty()) {
				return "Este cargo tiene algún empleado asociado por lo que no se puede pasar al estado Vacante. El estado vacante sólo puede tener candidatos asociados.";

			}
		}
		if (viejoEstado.equals("Vacante") && nuevoEstado.equals("Bloqueado")) {
			ArrayList<Candidato> candidatosAsociados = SIRHApp.getInstance().getDAOCandidato().getCargoAsociado(id);
			
                        for (Candidato c : candidatosAsociados) {
				if (!c.getEstado().equals("Descartado")) {
					return "Este cargo tiene candidatos no descartados asociados y por lo tanto no puede pasar al estado Bloqueado";

				}
			}
		}      
		return "";
	}

	public String validarInformacion(String nombre, String salarioBasico, Horario horario) {
		if (!verificarFormatoNombre(nombre)) {
			return ("El nombre no debe contener símbolos numéricos.");
		}

		if (!verificarLongitudNombre(nombre)) {
			return ("El nombre debe tener una longitud mínima de 8 caracteres y máxima de 30.");
		}

		if (!verificarFormatoSalarioBasico(salarioBasico)) {
			return ("El salario básico debe contener únicamente símbolos numéricos.");
		}

		if (!verificarLongitudSalarioBasico(salarioBasico)) {
			return ("El salario básico debe ser un valor real positivo mayor a $100.000 y menor a $1.000.000.000");
		}

		if (!verificarExistenciaHorario(horario)) {
			return ("Para crear un cargo debe asignarle un horario de trabajo.");
		}

		return ("");
	}

	public boolean verificarFormatoNombre(String nombre) {
		Pattern patternNombre = Pattern.compile("[^A-Za-zñáéíóú ]");
		Matcher matcherNombre = patternNombre.matcher(nombre);

		boolean esCadena = false;
		while (matcherNombre.find()) {
			esCadena = true;
		}
		return (!esCadena);

	}

	public boolean verificarLongitudNombre(String nombre) {
		return (nombre.length() >= 8 && nombre.length() <= 30);
	}

	public boolean verificarFormatoSalarioBasico(String salarioBasico) {

		if (salarioBasico.matches("\\d*\\.\\d*") || salarioBasico.matches("\\d*")) {
			return true;
		}
		return false;
	}

	public boolean verificarLongitudSalarioBasico(String salarioBasico) {
		boolean parse = true;
		double salario = 0;

		try {
			salario = Double.parseDouble(salarioBasico);

		} catch (NumberFormatException NFE) {
			parse = false;
		}

		return (parse && salario >= 100000 && salario <= Math.pow(10.0, 9.0));
	}

	public boolean verificarExistenciaHorario(Horario horario) {
            List<HorarioDia> horarioTMP = horario.getHorario();
		for (HorarioDia hd : horarioTMP) {
			if (hd.getInicioJor() != 0 || hd.getFinJor() != 0) {
				return true;
			}
		}

		return false;
	}

	protected DAO<Cargo> getDAO() {
		return SIRHApp.getInstance().getDAOCargo();
	}
}
